#!/usr/bin/env python
# -*- coding:utf-8 -*-

import datetime
import math
import json

from sqlalchemy import or_

from app import db
from models.notice import Notice
from utils import commons
from utils.response_code import RET, error_map_EN
from utils.loggings import loggings
from models import BaseModel


class NoticeController(Notice,BaseModel):

    # add
    @classmethod
    def add(cls, **kwargs):
        from utils.generate_id import GenerateID
        notice_id = GenerateID.create_random_id()
        
        try:
            model = Notice(
                notice_id=notice_id,
                publisher_id=kwargs.get('publisher_id'),
                title=kwargs.get('title'),
                content=kwargs.get('content'),
                notice_file_url=kwargs.get('notice_file_url'),
                status=kwargs.get('status'),
                publish_time=kwargs.get('publish_time'),
                is_recommend=kwargs.get('is_recommend'),
                create_time=kwargs.get('create_time'),
                update_time=kwargs.get('update_time'),
                
            )
            db.session.add(model)
            db.session.commit()
            results = {
                'add_time': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                'notice_id': model.notice_id,
                
            }
            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': results}
            
        except Exception as e:
            db.session.rollback()
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()

    # get
    @classmethod
    def get(cls, **kwargs):
        try:
            filter_list = [cls.is_delete == 0]
            if kwargs.get('notice_id'):
                filter_list.append(cls.notice_id == kwargs['notice_id'])
            else:
                if kwargs.get('publisher_id') is not None:
                    filter_list.append(cls.publisher_id == kwargs.get('publisher_id'))
                if kwargs.get('title'):
                    filter_list.append(cls.title == kwargs.get('title'))
                if kwargs.get('content'):
                    filter_list.append(cls.content == kwargs.get('content'))
                if kwargs.get('notice_file_url'):
                    filter_list.append(cls.notice_file_url == kwargs.get('notice_file_url'))
                if kwargs.get('status') is not None:
                    filter_list.append(cls.status == kwargs.get('status'))
                if kwargs.get('publish_time'):
                    filter_list.append(cls.publish_time == kwargs.get('publish_time'))
                if kwargs.get('is_recommend') is not None:
                    filter_list.append(cls.is_recommend == kwargs.get('is_recommend'))
                if kwargs.get('create_time'):
                    filter_list.append(cls.create_time == kwargs.get('create_time'))
                if kwargs.get('update_time'):
                    filter_list.append(cls.update_time == kwargs.get('update_time'))
                

            page = int(kwargs.get('Page', 1))
            size = int(kwargs.get('Size', 10))
            
            notice_info = db.session.query(cls).filter(*filter_list)
            
            count = notice_info.count()
            pages = math.ceil(count / size)
            notice_info = notice_info.limit(size).offset((page - 1) * size).all()
   
            #results = commons.query_to_dict(notice_info)
            results = cls.to_dict(notice_info)
            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'totalCount': count, 'totalPage': pages, 'data': results}
            
        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()

    # delete
    @classmethod
    def delete(cls, **kwargs):
        try:
            filter_list = [cls.is_delete == 0]
            if kwargs.get('notice_id'):
                primary_key_list = []
                for primary_key in str(kwargs.get('notice_id')).replace(' ', '').split(','):
                    primary_key_list.append(cls.notice_id == primary_key)
                filter_list.append(or_(*primary_key_list))
                
            else:
                if kwargs.get('publisher_id') is not None:
                    filter_list.append(cls.publisher_id == kwargs.get('publisher_id'))
                if kwargs.get('title'):
                    filter_list.append(cls.title == kwargs.get('title'))
                if kwargs.get('content'):
                    filter_list.append(cls.content == kwargs.get('content'))
                if kwargs.get('notice_file_url'):
                    filter_list.append(cls.notice_file_url == kwargs.get('notice_file_url'))
                if kwargs.get('status') is not None:
                    filter_list.append(cls.status == kwargs.get('status'))
                if kwargs.get('publish_time'):
                    filter_list.append(cls.publish_time == kwargs.get('publish_time'))
                if kwargs.get('is_recommend') is not None:
                    filter_list.append(cls.is_recommend == kwargs.get('is_recommend'))
                if kwargs.get('create_time'):
                    filter_list.append(cls.create_time == kwargs.get('create_time'))
                if kwargs.get('update_time'):
                    filter_list.append(cls.update_time == kwargs.get('update_time'))
                
            res = db.session.query(cls).filter(*filter_list).with_for_update()

            results = {
                'notice_id': []
            }
            for query_model in res.all():
                results['notice_id'].append(query_model.notice_id)

            res.update({'is_delete': 1})
            db.session.commit()

            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': results}

        except Exception as e:
            db.session.rollback()
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()
    
    # update
    @classmethod
    def update(cls, **kwargs):
        try:
            
            
            filter_list = [cls.is_delete == 0]
            filter_list.append(cls.notice_id == kwargs.get('notice_id'))
            
            res = db.session.query(cls).filter(*filter_list).with_for_update()
            if res.first():
                results = {
                    'update_time': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    'notice_id': res.first().notice_id,
                
                }
                
                res.update(kwargs)
                db.session.commit()
            else:
                results = {
                    'error': 'data dose not exist'
                }

            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': results}

        except Exception as e:
            db.session.rollback()
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()

    # batch add
    @classmethod
    def add_list(cls, **kwargs):
        param_list = kwargs.get('NoticeList')
        model_list = []
        for param_dict in param_list:
            from utils.generate_id import GenerateID
            notice_id = GenerateID.create_random_id()
            
            model = Notice(
                notice_id=notice_id,
                publisher_id=param_dict.get('publisher_id'),
                title=param_dict.get('title'),
                content=param_dict.get('content'),
                notice_file_url=param_dict.get('notice_file_url'),
                status=param_dict.get('status'),
                publish_time=param_dict.get('publish_time'),
                is_recommend=param_dict.get('is_recommend'),
                create_time=param_dict.get('create_time'),
                update_time=param_dict.get('update_time'),
                
            )
            model_list.append(model)
        
        try:
            db.session.add_all(model_list)
            db.session.commit()
            results = {
                'added_records': [],
                'add_time': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }
            for model in model_list:
                added_record = {}
                added_record['notice_id'] = model.notice_id
                
                results['added_records'].append(added_record)
                
            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': results}
            
        except Exception as e:
            db.session.rollback()
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()

    @staticmethod
    def delete(**kwargs):
        try:
            notice_id = kwargs.get('notice_id')
            notice = Notice.query.filter_by(notice_id=notice_id).first()
            
            # 如果通知不存在，返回错误信息
            if not notice:
                return {
                    'code': RET.NODATA,  # 使用合适的错误码，比如 404
                    'message': '通知不存在',
                    'data': None
                }
            
            # 如果通知存在，执行删除操作
            delete_time = datetime.now()
            
            # 可以是软删除
            notice.is_delete = 1
            notice.update_time = delete_time
            db.session.commit()
            
            return {
                'code': RET.OK,
                'message': 'success',
                'data': {
                    'notice_id': notice.notice_id,
                    'title': notice.title,
                    'delete_time': delete_time.strftime('%Y-%m-%d %H:%M:%S')
                }
            }
            
        except Exception as e:
            db.session.rollback()
            return {
                'code': RET.DBERR,
                'message': str(e),
                'data': None
            }

    # @staticmethod
    # def get(**kwargs):
    #     try:
    #         # 如果是获取单个通知
    #         if kwargs.get('notice_id'):
    #             notice = Notice.query.filter_by(notice_id=kwargs.get('notice_id')).first()
    #
    #             # 如果通知不存在
    #             if not notice:
    #                 return {
    #                     'code': RET.NODATA,
    #                     'message': '通知不存在',
    #                     'data': None
    #                 }
    #
    #             # 如果通知存在，返回完整数据
    #             return {
    #                 'code': RET.OK,
    #                 'message': 'success',
    #                 'data': {
    #                     'notice_id': notice.notice_id,
    #                     'title': notice.title,
    #                     'content': notice.content,
    #                     'publisher_id': notice.publisher_id,
    #                     'notice_file_url': notice.notice_file_url,
    #                     'status': notice.status,
    #                     'publish_time': notice.publish_time.strftime('%Y-%m-%d %H:%M:%S') if notice.publish_time else None,
    #                     'is_recommend': notice.is_recommend,
    #                     'is_delete': notice.is_delete,
    #                     'create_time': notice.create_time.strftime('%Y-%m-%d %H:%M:%S') if notice.create_time else None,
    #                     'update_time': notice.update_time.strftime('%Y-%m-%d %H:%M:%S') if notice.update_time else None
    #                 }
    #             }
    #
    #         # 如果是获取通知列表
    #         else:
    #             # 处理分页参数
    #             page = int(kwargs.get('Page', 1))
    #             size = int(kwargs.get('Size', 10))
    #
    #             # 构建查询
    #             query = Notice.query
    #
    #             # 添加其他查询条件
    #             if kwargs.get('title'):
    #                 query = query.filter(Notice.title.like(f"%{kwargs['title']}%"))
    #             if kwargs.get('publisher_id'):
    #                 query = query.filter_by(publisher_id=kwargs['publisher_id'])
    #             if kwargs.get('status'):
    #                 query = query.filter_by(status=kwargs['status'])
    #             if kwargs.get('is_recommend'):
    #                 query = query.filter_by(is_recommend=kwargs['is_recommend'])
    #
    #             # 默认不显示已删除的通知
    #             query = query.filter_by(is_delete=0)
    #
    #             # 获取总数
    #             total = query.count()
    #
    #             # 分页
    #             notices = query.offset((page - 1) * size).limit(size).all()
    #
    #             # 构建返回数据
    #             notice_list = []
    #             for notice in notices:
    #                 notice_list.append({
    #                     'notice_id': notice.notice_id,
    #                     'title': notice.title,
    #                     'content': notice.content,
    #                     'publisher_id': notice.publisher_id,
    #                     'notice_file_url': notice.notice_file_url,
    #                     'status': notice.status,
    #                     'publish_time': notice.publish_time.strftime('%Y-%m-%d %H:%M:%S') if notice.publish_time else None,
    #                     'is_recommend': notice.is_recommend,
    #                     'is_delete': notice.is_delete,
    #                     'create_time': notice.create_time.strftime('%Y-%m-%d %H:%M:%S') if notice.create_time else None,
    #                     'update_time': notice.update_time.strftime('%Y-%m-%d %H:%M:%S') if notice.update_time else None
    #                 })
    #
    #             return {
    #                 'code': RET.OK,
    #                 'message': 'success',
    #                 'data': notice_list,
    #                 'totalCount': total,
    #                 'totalPage': (total + size - 1) // size
    #             }
    #
    #     except Exception as e:
    #         return {
    #             'code': RET.DBERR,
    #             'message': str(e),
    #             'data': None
    #         }
